<?php

	/**
	 * thumb class to scale and resize images from files uploaded or existing files.
	 * it can handle multiple files at the same time. 
	 * 
	 * http://de.kioskea.net/contents/courrier-electronique/mime.php3
	 * http://www.iana.org/assignments/media-types/image/ 
	 *
	 * @version v.1.0.2 
	 * @author basil suter
	 * 
	 * v.1.0.2 	[20.08.09] improved and made a stable first release
	 * v.1.0.1 	[19.08.09] first beta tests and releases of thumb class
	 */	
	Class Yomm_Image_Thumb {
		/**
		 * @var $plugin_dir [char] the path which includes all mime plugin classes. ex: 'plugins/'
		 */
		public $plugin_dir = 'plugins/';
		
		/**
		 * @var $plugin_static_method [char] its the name of the static method in plugin classes.
		 */
		public $plugin_static_method = 'resample';
		
		/**
		 * @var $plugin_shema [char] the strucutre for the name of the plugin classes.
		 */
		public $plugin_shema = '{type}.class.php';

		/**
		 * @var $error [char] it contains the error message which is given by the catch exception function.
		 */
		public $error = null;
		
		/**
		 * @var $save_dir [char] its the path to the folder which all images will be stored. (!trailaingslash!) ex: 'thumbs/';
		 */
		public $save_dir = null;
				
		/**
		 * @var $sizes [array] it contains all to convert sizes. ex: array ('thumb' => 100, 'big' => 400);
		 */
		public $sizes = array();
		
		/**
		 * @var $images [array] it contains all files which should be converted! ex: array('source' => 'path/to/img.jpg', 'mime_type' => 'jpeg')
		 */
		public $images = array();
	
		/**
		 * @var $mimes [array] all available mime types will be stored in this array. to load the plugin for each fo them.
		 */
		public $mimes = array();
		
		/**
		 * @var $files [array] this is the return array. after processgin convert() all image infos will be stored in this array.
		 */
		public $files = array();
	    
		/**
		 * singleton identifier
		 * @var obj
		 */
		static private $instance = null;
		
	    /**
	     * set $images
	     * @param $source [char] mostly the tmp file path but can be real path to. ex: 'path/to/my/image.png'
	     * @param $mime_type [char] it contains the file mime_type. ex: 'jpeg'
	     */
	    public function setImage($source, $mime_type)
		{
	        $this->images[] = array(
				'source' => $source,
				// 'mime_type' => str_replace('image/', '', $mime_type) // TODO: now we change this information cause already deliverin it
				'mime_type' => $mime_type
			);
	    }
	    
	    /**
	     * set $sizes
	     * @param $sizes [array] to convert sizes in pixels. ex: array('thumb' => 100, 'big' => 400);
	     */
	    public function setSizes($sizes)
		{
	    	if(is_array($sizes)) $this->sizes = $sizes;
	    }
		
		/**
		 * set $save_dir
		 * @param $save_dir [char] contains the absolut path to the saving folder with trailing slash! ex: 'images/thumbs/';
		 * @return 
		 */
		public function setSaveDir($save_dir)
		{
			if(is_string($save_dir) && file_exists($save_dir)) $this->save_dir = $save_dir;
		}
		
		/**
		 * return $files after convert()
		 * @return array
		 */
		public function getFiles()
		{
			return $this->files;
		}

		/**
	 	 * single ton method
	 	 * @return 
	 	 */
		static public function getInstance()
		{
			if(self::$instance === null){
				self::$instance = new self;
			}
			return self::$instance;
		}
		
		/**
		 * convert all given files and store
		 * 
		 * this is the main method of this class. it checks all vars for availability, execute the 
		 * pluginLoad method, which will include the files in it selfs. for each all files and those
		 * will be for eached in the sizes. the user func (in our case its are classes) will be executed
		 * and returns boolean value. if true all informations will be stored in $files array and returning
		 * true.
		 * 
		 * @return boolean
		 */
		public function convert()
		{
			$this->files = array();
			
			if(empty($this->save_dir))
			{
				throw new Yomm_Error('The save_dir ist not set or was not found. use setSaveDir($name) to settle.');
			}
			
			// if there are no images or no sizes in the array. return error. can not convert empty que
			if((count($this->images) == 0) || (count($this->sizes) == 0))
			{
				throw new Yomm_Error('images, sizes not valid! Verify those imports first.');
				return false;
			}
			
			
			// foreach all images
			foreach($this->images as $image_key => $image_value)
			{
				$file_name = mktime() . rand();
				// foreach all sizes per image
				foreach($this->sizes as $size_key => $size_value)
				{
					$file_name_full = $file_name . '_' . $size_key . '.' . $image_value['mime_type'];
					
					// Yomm_Class_Namingspace Fix
					$class = "Yomm_Image_Plugin_".ucfirst($image_value['mime_type']);
					
					if(call_user_func_array(array($class, $this->plugin_static_method), array($this->resize($image_key, $size_value), $image_value, $this->save_dir . $file_name_full)))
					{
						// file successfully converted, now store all informations in $files array.
						$this->files[$file_name]['files'][$size_key] = $file_name_full;
						$this->files[$file_name]['name'] = $file_name;
						$this->files[$file_name]['mime_type'] = $image_value['mime_type'];
						$this->files[$file_name]['save_dir'] = $this->save_dir;
					}
				}
			}
			// clear files list and image list 
			$this->images = array();
			
			// return success EOF
			return true;
		}
		
		/**
		 * get the new width and height for the inserted thumb size.
		 * 
		 * @param $image_key [char] array key from $images array. ex: 0
		 * @param $resize [char] size of the calculating base. ex: 400 (its pixel value)
		 * @return array
		 */
		private function resize($image_key, $resize)
		{
			list($src_width, $src_height) = getimagesize($this->images[$image_key]['source']);
			// if landscape mode
			if($src_width >= $src_height)
			{
	  			$tb_width = $resize;
	  			$tb_height = $src_height * $resize / $src_width;
	  		}
	  		// if portrait mode
			if($src_width < $src_height)
			{
	  			$tb_height = $resize;
	  			$tb_width = $src_width * $resize / $src_height;
	  		}
			
			return array($tb_width, $tb_height);		
		}
		
		/**
		 * find out which mime types are available in $images list. store them into
		 * a new array and load the plugin for those, if this mime plugin is available.
		 * 
		 * @return boolean
		 */
		/*
		private function pluginLoad()
		{
			foreach($this->images as $key => $value)
			{
				if(!in_array($value['mime_type'], $this->mimes))
				{
					if(!$this->pluginInclude($value['mime_type']))
					{
						break;
						return false;
					}
					
					$this->mimes[] = $value['mime_type'];
				}
			}
			
			return true;
		}
		*/
		
		/**
		 * try to include the file. if it is available and the include was working 
		 * it will return true.
		 * 
		 * @param $mime_type [char] the mime type from pluginLoad / $images array. ex: 'jpeg'
		 * @return boolean
		 */
		/*
		private function pluginInclude($mime_type)
		{
			$plugin_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . $this->plugin_dir . ucfirst(str_replace('{type}', $mime_type, $this->plugin_shema));
			
			if(!file_exists($plugin_file))
			{
				throw new Yomm_Error('The plugin for mime type '.$mime_type.' is not available!');
				return false;
			}
			
			if(!include_once($plugin_file))
			{
				throw new Yomm_Error('error while including image file plugin / extension for mime type: ' . $mime_type);
				return false;
			}
			
			return true;
		}	
		*/	
	}
?>